package com.cyf.wechat.service.impl;

import com.cyf.activemq.network.bean.*;
import com.cyf.activemq.network.bean.person.MqEmployeeItem;
import com.cyf.activemq.network.bean.person.MqGetEventRecordReq;
import com.cyf.activemq.network.bean.person.MqGetEventRecordRsp;
import com.cyf.activemq.service.MqService;
import com.cyf.activemq.service.SendMsgService;
import com.cyf.db.bean.*;
import com.cyf.db.mapper.*;
import com.cyf.redis.RedisService;
import com.cyf.service.CheckParam;
import com.cyf.service.CommonService;
import com.cyf.service.UserService;
import com.cyf.service.bean.CustomException;
import com.cyf.util.BasicProperties;
import com.cyf.util.DateUtil;
import com.cyf.util.ObjectMapperUtils;
import com.cyf.util.PayOrderMessageList;
import com.cyf.wechat.network.bean.*;
import com.cyf.wechat.service.WechatSendService;
import com.cyf.wechat.service.WechatService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by cage on 2016/10/8.
 */
@Service
public class WechatServiceImpl implements WechatService {

    private static final Logger logger = LoggerFactory.getLogger(WechatServiceImpl.class);

    private static final int oneDay = 24 * 60 * 60;

    @Autowired
    private InOutParkingMapper inOutParkingMapper;
    @Autowired
    private InParkingMapper inParkingMapper;
    @Autowired
    private WechatSendService wechatSendService;
    @Autowired
    private CarMapper carMapper;
    @Autowired
    private PersonMapper personMapper;
    @Autowired
    private FeeDetailMapper feeDetailMapper;
    @Autowired
    private ParkingMapper parkingMapper;
    @Autowired
    private PayOrderMapper payOrderMapper;
    @Autowired
    private OnlinePayUserMapper onlinePayUserMapper;
    @Autowired
    private AppCarMapper appCarMapper;
    @Autowired
    private AppUserCarMapper appUserCarMapper;
    @Autowired
    private LocalIntervieweeMapper localIntervieweeMapper;
    @Autowired
    private VisitorRecordMapper visitorRecordMapper;
    @Autowired
    private InviteRecordMapper inviteRecordMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LocalAdminparaMapper localAdminparaMapper;
    @Autowired
    private VisitorRecordSendMapper visitorRecordSendMapper;
    @Autowired
    private VisitorImgMapper visitorImgMapper;
    @Autowired
    private FeeGroupMapper feeGroupMapper;
    @Autowired
    private UsersWechatMapper usersWechatMapper;

    @Autowired
    private SendMsgService sendMsgService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private BasicProperties basicProperties;
    @Autowired
    private CommonService commonService;
    @Autowired
    private MqService mqService;
    @Autowired
    private CheckParam checkParam;
    @Autowired
    private LocalCarWashCouponMapper localCarWashCouponMapper;
    @Autowired
    private CarWashDetailMapper carWashDetailMapper;
    @Autowired
    private UserService userService;


    @Override
    public WechatGetFeeRsp getFee(WechatGetFeeReq req) {
        WechatGetFeeRsp rsp = new WechatGetFeeRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setPlate(req.getPlate());
        rsp.setTime(req.getTime());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            checkParam.getUserByOpenid(req.getOpenid());
            InParking inParking = inParkingMapper.getByPlate(req.getPlate());
            if (inParking == null) {
                rsp.setStrError("该车辆没有入场,获取计费信息失败！");
                logger.info("微信车辆({})获取计费信息失败 ：{}", req.getPlate(), "该车辆没有入场");
                return rsp;
            }
            Parking parking = parkingMapper.getParkingById(inParking.getParkingId());
            if (parking == null) {
                rsp.setStrError("该车辆没有入场,获取计费信息失败！");
                logger.info("微信车辆({})获取计费信息失败 ：{}", req.getPlate(), "入场信息中车场id不存在！");
                return rsp;
            }
            rsp.setParking(parking.getName());

            commonService.checkSupportOnlinePay(inParking);

            MqGetFeeRsp mqGetFeeRsp = mqService.getFee(req.getPlate(), parking.getId(), DateUtil.parseDate(req.getTime(), "yyyy-MM-dd HH:mm"));
            rsp.setResult(WechatBusinessRsp.SUCCESS);
            rsp.setFee(mqGetFeeRsp.getFee());
            rsp.setInParkingId(mqGetFeeRsp.getInParkingId());
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("获取计费信息失败！");
            logger.error("微信车辆(" + req.getPlate() + ")获取计费信息异常 ：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatPayFeeRsp payFee(WechatPayFeeReq req) {
        WechatPayFeeRsp rsp = new WechatPayFeeRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            checkParam.getUserByOpenid(req.getOpenid());
            InParking inParking = inParkingMapper.getByPlate(req.getPlate());
            if (inParking == null) {
                rsp.setStrError("该车辆没有入场,支付完成消息发送车场失败！");
                logger.info("微信车辆({})支付完成消息返回失败 ：{}", req.getPlate(), "该车辆没有入场");
                return rsp;
            }
            Parking parking = parkingMapper.getParkingById(inParking.getParkingId());
            if (parking == null) {
                rsp.setStrError("查找车场失败！");
                return rsp;
            }
            // 保存微信支付订单
            PayOrder payOrder = new PayOrder();
            payOrder.setOpenid(req.getOpenid());
            payOrder.setFee(req.getFee());
            payOrder.setOrderNo(req.getOrderNo());
            payOrder.setTransactionId(req.getTransactionId());
            payOrder.setParkingId(inParking.getParkingId());
            payOrder.setPlate(req.getPlate());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            payOrder.setOutTime(format.parse(req.getOutTime()));
            Date curDate = new Date();
            payOrder.setCreatedTime(curDate);
            payOrder.setPayTime(curDate);
            if ("1".equals(req.getFlag())) {
                payOrder.setFeeType(PayOrder.FEETYPE_HELP);
            } else {
                payOrder.setFeeType(PayOrder.FEETYPE_SELF);
            }
            payOrder.setTradeType(PayOrder.TRADETYPE_WECHAT);
            payOrder.setPayWay(PayOrder.PAY_WAY_WECHAT);
            payOrder.setPayStatus(PayOrder.PAY_SUCCESS);
            payOrder.setInfoId(req.getInParkingId());
            payOrder.setInfoType(PayOrder.INFOTYPE_INPARKING);
            payOrderMapper.insertPayOrder(payOrder);

            UsersWechat usersWechat = usersWechatMapper.getByOpenid(req.getOpenid());
            if (usersWechat != null) {
                wechatSendService.pay(usersWechat.getApiUserId(), req.getPlate(), parking.getName(), usersWechat.getOpenid(), format.format(curDate), req.getFee());
            }
            if (req.getFlag() != null && req.getFlag().equals("1")) {    // 帮人支付  通知车主
                AppCar appCar = appCarMapper.getByPlate(req.getPlate());
                if (appCar != null) {
                    List<User> users = appUserCarMapper.getUserByCarId(appCar.getId());
                    if (users != null && users.size() > 0) {
                        for (User user : users) {

                            List<UsersWechat> usersWechatList = usersWechatMapper.listByUserId(user.getId());
                            for (UsersWechat item : usersWechatList) {
                                wechatSendService.pay(item.getApiUserId(), req.getPlate(), parking.getName(), item.getOpenid(), format.format(curDate), req.getFee());
                            }
                        }
                    }
                }
            }

            // 将支付消息添加到消息队列中
            PayOrderMessageList.addPayOrderMessage(payOrder);
            rsp.setResult(WechatBusinessRsp.SUCCESS);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("服务器异常！");
            logger.error("微信车辆(" + req.getPlate() + ")保存支付信息异常 ：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatGetCarsRsp getInCars(WechatGetCarsReq req) {
        WechatGetCarsRsp rsp = new WechatGetCarsRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            ArrayList<String> list = new ArrayList<>();
            // 查找 微信用户注册的全部车辆
            User user = checkParam.getUserByOpenid(req.getOpenid());
            List<AppCar> appCars = appUserCarMapper.getCarByUserId(user.getId());
            if (appCars != null) {  // 查询 微信用户注册的已入场车辆
                for (AppCar car : appCars) {
                    InParking inParking = inParkingMapper.getByPlate(car.getPlate());
                    if (inParking != null) {
                        list.add(car.getPlate());
                    }
                }
            }
            rsp.setCars(list);
            rsp.setResult(0);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("获取入场的车牌号失败！");
            logger.error("微信用户(" + req.getOpenid() + ")获取自己已入场的车辆异常：{}", e);
        }
        return rsp;
    }


    @Override
    public WechatInOutParkingRsp queryInOutParking(WechatInOutParkingReq req) {
        WechatInOutParkingRsp rsp = new WechatInOutParkingRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User user = checkParam.getUserByOpenid(req.getOpenid());
            List<AppCar> cars = appUserCarMapper.getCarByUserId(user.getId());
            if (cars == null) {
                rsp.setStrError("没有车辆！");
                return rsp;
            }
//			ArrayList<Integer> ids = new ArrayList<Integer>();	// 基础数据车辆上传，inoutparking中可能没有id
            String[] plates = new String[3];
            for (int i = 0; i < cars.size(); i++) {
                if (i > 2) {
                    continue;
                }
                plates[i] = cars.get(i).getPlate();
            }

            ArrayList<WechatInOutParking> list = new ArrayList<>();
            List<InOutParking> inOutParkings = inOutParkingMapper.getByTimeAndPlate(req.getInTime(), req.getOutTime(), plates[0], plates[1], plates[2], req.getStart(), req.getEnd());
            if (inOutParkings == null) {
                rsp.setStrError("暂无行车记录！");
                logger.error("在inoutparking表中查询车辆行车记录({} 至 {})失败，数据库返回null", req.getInTime(), req.getOutTime());
                return rsp;
            }
            for (InOutParking inOutParking : inOutParkings) {
                WechatInOutParking outParking = new WechatInOutParking();
                outParking.setPlate(inOutParking.getCarLicense());
                outParking.setParking(inOutParking.getParkingName());
                if (inOutParking.getPrimaryInTime() != null) {
                    outParking.setInTime(DateUtil.formatDate(inOutParking.getPrimaryInTime(), "HH:mm:ss"));
                }
                if (inOutParking.getPrimaryOutTime() != null) {
                    outParking.setOutTime(DateUtil.formatDate(inOutParking.getPrimaryOutTime(), "HH:mm:ss"));
                    outParking.setDateStr(DateUtil.formatDate(inOutParking.getPrimaryOutTime(), "yyyy-MM-dd"));
                }

                list.add(outParking);
            }
            rsp.setResult(WechatBusinessRsp.SUCCESS);
            rsp.setList(list);
            return rsp;
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("查询行车记录失败！");
            logger.error("查询行车记录(" + req.getInTime() + " 至 " + req.getOutTime() + ")异常：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatQueryFeedetailRsp queryFeedetail(WechatQueryFeedetailReq req) {
        WechatQueryFeedetailRsp rsp = new WechatQueryFeedetailRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User user = checkParam.getUserByOpenid(req.getOpenid());
            List<AppCar> cars = appUserCarMapper.getCarByUserId(user.getId());
            if (cars == null) {
                rsp.setStrError("没有车辆！");
                return rsp;
            }
            String[] plates = new String[3];
            for (int i = 0; i < cars.size(); i++) {
                if (i > 2) {
                    continue;
                }
                plates[i] = cars.get(i).getPlate();
            }

            ArrayList<WechatQueryFeedetailRsp.WechatQueryFeedetailItem> list = new ArrayList<>();
            List<InOutParking> inOutParkings = inOutParkingMapper.getByPlates(plates[0], plates[1], plates[2], req.getStart(), req.getEnd());
            if (inOutParkings == null || inOutParkings.size() == 0) {
                rsp.setStrError("暂无行车记录！");
                return rsp;
            }
            for (InOutParking inOutParking : inOutParkings) {
                WechatQueryFeedetailRsp.WechatQueryFeedetailItem item = new WechatQueryFeedetailRsp.WechatQueryFeedetailItem();
                item.setPlate(inOutParking.getCarLicense());
                item.setParking(inOutParking.getParkingName());
                if (inOutParking.getPrimaryInTime() != null) {
                    item.setInTime(DateUtil.formatDate(inOutParking.getPrimaryInTime(), "yyyy-MM-dd HH:mm"));
                }
                if (inOutParking.getPrimaryOutTime() != null) {
                    item.setOutTime(DateUtil.formatDate(inOutParking.getPrimaryOutTime(), "yyyy-MM-dd HH:mm"));
                    item.setDateStr(DateUtil.formatDate(inOutParking.getPrimaryOutTime(), "yyyy-MM-dd"));
                }
                item.setParkingId(inOutParking.getParkingId());
                item.setInoutparkingId(inOutParking.getId());
                item.setLocalInoutparkingId(inOutParking.getLocalInoutparkingId());
                Integer actualFee = feeDetailMapper.getSumActualFeeAndWechatFee(plates[0], plates[1], plates[2],inOutParking.getParkingId(), inOutParking.getLocalInoutparkingId());
                item.setActualFee(actualFee);
                list.add(item);
            }
            rsp.setResult(WechatBusinessRsp.SUCCESS);
            rsp.setList(list);
            return rsp;
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("查询行车记录失败！");
            logger.error("查询行车记录异常：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatGetFeeRateRsp getFeeRate(WechatGetFeeRateReq req) {
        WechatGetFeeRateRsp rsp = new WechatGetFeeRateRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User user = checkParam.getUserByOpenid(req.getOpenid());
            List<AppCar> appCars = appUserCarMapper.getCarByUserId(user.getId());
            if (appCars == null || appCars.size() == 0) {
                rsp.setStrError("没有车辆，无法充值！");
                return rsp;
            }
            // 车辆费率信息
            List<FeeRateItem> feeRateItems = new ArrayList<>();
            // 车场id : 车辆信息
            Map<Integer, List<FeeRateItem>> map = new HashMap<>();
            for (AppCar appCar : appCars) {
                List<Car> cars = carMapper.getByPlate(appCar.getPlate());
                if (cars == null || cars.size() == 0) {
                    logger.info("车辆({})未在任何车场登记", appCar.getPlate());
                    continue;
                }
                FeeRateItem item = new FeeRateItem();
                item.setPlate(appCar.getPlate());
                List<Integer> parkingIds = new ArrayList<>();
                List<String> parkingNames = new ArrayList<>();
                for (Car car : cars) {
                    logger.info("车辆({})在车场({})的({})名下登记！", appCar.getPlate(), car.getParkingId(), car.getPersonId());
                    Parking parking = parkingMapper.getParkingById(car.getParkingId());
                    if (parking == null) {
                        continue;
                    }
                    parkingIds.add(car.getParkingId());
                    parkingNames.add(parking.getName());
                }
                item.setParkingId(parkingIds);
                item.setParkingName(parkingNames);

                feeRateItems.add(item);

                for (Integer parkingId : parkingIds) {
                    List<FeeRateItem> list = map.get(parkingId);
                    if (list == null) {
                        list = new ArrayList<>();
                    }
                    list.add(item);
                    map.put(parkingId, list);
                }
            }
            boolean flag = false;
            if (map.size() == 0) {
                logger.info("车辆未在车场登记，无法充值！");
                rsp.setStrError("车辆未在车场登记，无法充值！");
                return rsp;
            }

            for (Integer parkingId : map.keySet()) {
                List<FeeRateItem> list = map.get(parkingId);

                ArrayList<String> plates = new ArrayList<>();
                for (FeeRateItem feeRateItem : list) {
                    plates.add(feeRateItem.getPlate());
                }
                try {
                    MqGetFeeRateRsp getFeeRateRsp = mqService.getFeeRate(parkingId, plates);

                    logger.info("获取车场({})的月卡表单成功！", parkingId);
                    flag = true;
                    Map<String, Integer> fees = getFeeRateRsp.getFees();
                    Map<String, Integer> carports = getFeeRateRsp.getCarports();

                    for (FeeRateItem feeRateItem : feeRateItems) {
                        for (String plate : plates) {
                            if (feeRateItem.getPlate().equals(plate)) {
                                int index = feeRateItem.getParkingId().indexOf(parkingId);
                                if (index > -1) {
                                    List<Integer> feeRates = feeRateItem.getFeeRates();
                                    int size = feeRates.size();
                                    for (int i = 0; i < index - size + 1; i++) {
                                        feeRates.add(null);
                                    }
                                    feeRates.set(index, fees.get(plate));
                                    List<Integer> carportNums = feeRateItem.getCarports();
                                    size = carportNums.size();
                                    for (int i = 0; i < index - size + 1; i++) {
                                        carportNums.add(null);
                                    }
                                    carportNums.set(index, carports.get(plate));
                                }
                            }
                        }
                    }

                } catch (CustomException e) {
                    logger.info("获取车场({})的月卡表单失败！", parkingId);
                    for (FeeRateItem feeRateItem : feeRateItems) {
                        int index = feeRateItem.getParkingId().indexOf(parkingId);
                        if (index > -1) {
                            List<Integer> feeRates = feeRateItem.getFeeRates();
                            int size = feeRates.size();
                            for (int i = 0; i < index - size + 1; i++) {
                                feeRates.add(null);
                            }
                            feeRates.set(index, null);

                            List<Integer> carportNums = feeRateItem.getCarports();
                            size = carportNums.size();
                            for (int i = 0; i < index - size + 1; i++) {
                                carportNums.add(null);
                            }
                            carportNums.set(index, null);
                        }

                    }
                }
            }
            if (flag) {
                rsp.setResult(0);
                rsp.setFeeRateItems(feeRateItems);
            } else {
                rsp.setStrError("网络超时！");
            }

        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("无法充值！");
            logger.info("获取月卡充值表单页面异常：{}", e);
        }
        return rsp;
    }

    @Override
    public void carRecharge(WechatCarRechargeReq req) {

        try {
            // 插入feedetail
            FeeDetail feeDetail = new FeeDetail();
            logger.info("-------在feeDetail表中保存微信用户月卡充值完成消息！--------");
            Car car = carMapper.getByPlateAndParkingId(req.getPlate(), req.getParkingId());
            if (car == null) {
                logger.info("在车场({})查找车辆({})失败！", req.getParkingId(), req.getPlate());
            } else {
                Person person = personMapper.getById(car.getPersonId());
                if (person == null) {
                    logger.info("查找人员({})失败！", car.getPersonId());
                } else {
                    feeDetail.setCloudPersonId(person.getId());
                    feeDetail.setPersonID(person.getLocalPersonId());
                    feeDetail.setPersonName(person.getName());
                }
            }
            Date date = new Date();
            feeDetail.setRecharge(req.getFee());
            feeDetail.setCreatedTime(date);
            feeDetail.setFeeType("月卡充值");
            feeDetail.setParkingId(req.getParkingId());
            feeDetail.setPaidOnline(1);
            feeDetail.setCreatedUserName("网络充值");
            feeDetailMapper.insertCarRecharge(feeDetail);

            // 保存订单
            logger.info("-------保存微信用户月卡充值完成订单！--------");
            PayOrder payOrder = new PayOrder();
            payOrder.setPlate(req.getPlate());
            payOrder.setOpenid(req.getOpenid());
            payOrder.setFee(req.getFee());
            payOrder.setOrderNo(req.getOrderNo());
            payOrder.setTransactionId(req.getTransactionId());
            payOrder.setParkingId(req.getParkingId());
            payOrder.setFeeType(PayOrder.FEETYPE_RECHARGE);
            payOrder.setCreatedTime(date);
            payOrder.setTradeType(PayOrder.TRADETYPE_WECHAT);
            payOrder.setPayWay(PayOrder.PAY_WAY_WECHAT);
            payOrder.setPayStatus(PayOrder.PAY_SUCCESS);
            payOrder.setPayTime(date);
            payOrder.setMonth(req.getMonth());
            payOrder.setInfoId(feeDetail.getId());
            payOrder.setInfoType(PayOrder.INFOTYPE_FEEDETAIL);
            payOrderMapper.insertPayOrder(payOrder);

            // 加入消息队列中，准备下发车场
            PayOrderMessageList.addPayOrderMessage(payOrder);

        } catch (Exception e) {
            logger.error("微信用户月卡充值后保存信息异常：{}", e);
        }
    }


    @Override
    public WechatEventRecordRsp getEventRecord(WechatEventRecordReq req) {
        WechatEventRecordRsp rsp = new WechatEventRecordRsp();
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            String uuid = UUID.randomUUID().toString();
            MqGetEventRecordReq mqGetEventRecordReq = new MqGetEventRecordReq();
            mqGetEventRecordReq.setOptid(MqBusinessOpt.PERSON_GET_EVENTRECORD);
            mqGetEventRecordReq.setUuid(uuid);
            mqGetEventRecordReq.setDeptId(req.getDeptId());
            mqGetEventRecordReq.setDate(req.getDate());
            sendMsgService.sendQueueMessageText(ObjectMapperUtils.getObjectMapper().writeValueAsString(mqGetEventRecordReq));
            Object result = redisService.getWithExpireTime(uuid, basicProperties.getAppNetworkTimeOut());
            if (result == null) {
                rsp.setResult(WechatBusinessRsp.FAIL);
                rsp.setStrError("网络超时！");
                logger.info("消息队列中获取消息失败！");
                return rsp;
            }
            MqGetEventRecordRsp mqGetEventRecordRsp = (MqGetEventRecordRsp) result;
            if (mqGetEventRecordRsp.getResult() == MqBusinessRsp.SUCCESS) {
                rsp.setResult(WechatBusinessRsp.SUCCESS);
                List<MqEmployeeItem> items = mqGetEventRecordRsp.getEmployeeItems();
                List<EmployeeItem> employeeItems = new ArrayList<>();
                for (MqEmployeeItem item : items) {
                    EmployeeItem employeeItem = new EmployeeItem();
                    BeanUtils.copyProperties(item, employeeItem);
                    employeeItems.add(employeeItem);
                }
                rsp.setEmployeeItems(employeeItems);
            } else {
                rsp.setResult(WechatBusinessRsp.FAIL);
                rsp.setStrError("获取信息失败！");
            }
        } catch (Exception e) {
            rsp.setResult(WechatBusinessRsp.FAIL);
            rsp.setStrError("服务器异常！");
            logger.error("获取人管平台的部门(" + req.getDeptId() + ")的人员出入记录异常 ：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatInviteRsp invite(WechatInviteReq req) {
        WechatInviteRsp rsp = new WechatInviteRsp();
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User interviewee = checkParam.getUserByOpenid(req.getOpenid());

            if (interviewee.getMobile().equals(req.getMobile())) {
                rsp.setStrError("自己不能邀请自己！");
                return rsp;
            }
            // TODO: 2017/9/25 重复邀请
            InviteRecord inviteRecord = inviteRecordMapper.getByIntervieweeIdAndMobile(interviewee.getId(), req.getMobile());
            if (inviteRecord != null) {
                rsp.setStrError("请勿重复邀请！");
                return rsp;
            }

            // 创建邀请记录
            inviteRecord = new InviteRecord();
            inviteRecord.setIntervieweeId(interviewee.getId());
            inviteRecord.setCreatedTime(new Date());
            inviteRecord.setMobile(req.getMobile());
            inviteRecord.setEndTime(DateUtil.getDateAfterSeconds(new Date(), 3 * oneDay));
            inviteRecordMapper.insertInviteRecord(inviteRecord);

            Integer apiUserId = usersWechatMapper.getApiUserIdByOpenid(req.getOpenid());

            // 判断访客是否是微信用户
            User user = userMapper.getByMobile(req.getMobile());

            String openid = usersWechatMapper.getOpenidByUserIdAndApiUserId(user.getId(), apiUserId);
            if (StringUtils.isEmpty(openid)) {
                // 非微信公众号用户，发短信通知
                // TODO: 2017/9/22
//                String text = SmsUtils.getTxtForVisitorSystem(interviewee.getMobile());
//                SmsUtils.SendSms(text, req.getMobile());
            } else {
                // 是微信公众号用户，发送模板消息通知
//                String mobile = interviewee.getMobile();
                wechatSendService.invite(apiUserId, openid, interviewee.getMobile(), inviteRecord.getCreatedTime());
            }
            rsp.setResult(WechatBusinessRsp.SUCCESS);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("服务器异常！");
            logger.error("受访者邀请访客异常：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatApplyVisitRsp applyVisit(WechatApplyVisitReq req) {
        WechatApplyVisitRsp rsp = new WechatApplyVisitRsp();
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User visitor = checkParam.getUserByOpenid(req.getOpenid());
            UsersWechat usersWechat = usersWechatMapper.getByOpenid(req.getOpenid());
            Integer apiUserId = usersWechat.getApiUserId();

            User interviewee = userMapper.getByMobile(req.getIntervieweeMobile());
            Date estimateVisitorTime = DateUtil.convertSeconds2Date(req.getEstimateVisitorTime());
            if (estimateVisitorTime.getTime() < System.currentTimeMillis()) {
                rsp.setStrError("预约时间不能小于当前时间！");
                return rsp;
            }

            if (visitor.getMobile().equals(req.getIntervieweeMobile())) {
                rsp.setStrError("自己不能预约自己！");
                return rsp;
            }

            // 查询是否已经申请，上次自动取消
            VisitorRecord lastVisitorRecord = visitorRecordMapper.getByVisitorIdAndMobile(visitor.getId(), req.getIntervieweeMobile());
            if (lastVisitorRecord != null) {
                visitorRecordMapper.updateStatusById(VisitorRecord.STATUS_CANCEL, lastVisitorRecord.getId());
            }

            // 保存访客记录
            VisitorRecord visitorRecord = new VisitorRecord();
            InviteRecord inviteRecord = null;
            if (interviewee != null) {
                visitorRecord.setIntervieweeId(interviewee.getId());
                inviteRecord = inviteRecordMapper.getByIntervieweeIdAndMobile(interviewee.getId(), visitor.getMobile());
            }

            visitorRecord.setMobile(req.getIntervieweeMobile());
            visitorRecord.setVisitorId(visitor.getId());
            visitorRecord.setCreatedTime(new Date());
            visitorRecord.setEstimateVisitorTime(estimateVisitorTime);
            visitorRecord.setEndTime(DateUtil.getDateAfterSeconds(estimateVisitorTime, 3 * oneDay));
            visitorRecord.setName(req.getName());
            visitorRecord.setMemo(req.getMemo() != null ? req.getMemo().trim() : null);
            if (inviteRecord != null) {
                visitorRecord.setStatus(VisitorRecord.STATUS_PASS);
            } else {
                visitorRecord.setStatus(VisitorRecord.STATUS_WAIT_PASS);
            }
            visitorRecord.setPlate(req.getPlate());
            visitorRecord.setOrderNo(VisitorRecord.generateOrderNo());
            visitorRecord.setApiUserId(apiUserId);
            visitorRecordMapper.insertVisitorRecord(visitorRecord);
//            if (req.getPlate() != null && req.getPlate().trim().length() > 0) {
//                String[] plates = req.getPlate().split(",");
//                for (String plate : plates) {
//                    VisitorCar visitorCar = new VisitorCar();
//                    visitorCar.setVisitorRecordId(visitorRecord.getId());
//                    visitorCar.setPlate(plate.trim().toUpperCase());
//                    visitorCarMapper.insertVisitorCar(visitorCar);
//                }
//            }


            // 通知被访客
            String intervieweeName = "";    // 被访客姓名
            if (interviewee == null) {
                // TODO: 2017/9/18 受访者未关注微信公众号，短信提醒
                logger.info("发短信通知");
                //                String text = SmsUtils.getTxtForVisitorSystem(interviewee.getMobile());
//                SmsUtils.SendSms(text, req.getMobile());
            } else {
                String openid = usersWechatMapper.getOpenidByUserIdAndApiUserId(interviewee.getId(), apiUserId);
                if (StringUtils.isEmpty(openid)) {
                    // TODO: 2018/7/27     发短信通知
                } else {
                    // 公众号通知被访客者
                    wechatSendService.applyVisit(apiUserId, openid, visitorRecord.getName(), visitorRecord.getMemo(), visitorRecord.getId());
                    // 向车场发送访客记录
                    if (inviteRecord != null) {
                        intervieweeName = saveVisitorRecordSend(visitorRecord);
                    }
                }
            }

            // 该访客已被邀请
            if (inviteRecord != null) {
                // 删除邀请记录
                inviteRecordMapper.deleteById(inviteRecord.getId());
                // 发送成功通知
                String estimateVisitorTimeStr = DateUtil.formatDate(visitorRecord.getEstimateVisitorTime(), "yyyy-MM-dd HH:mm");
                String endTimeStr = DateUtil.formatDate(visitorRecord.getEndTime(), "yyyy-MM-dd HH:mm");

                wechatSendService.visitPass(intervieweeName, apiUserId, usersWechat.getOpenid(), visitorRecord.getName(), interviewee.getMobile(), estimateVisitorTimeStr, endTimeStr, visitorRecord.getOrderNo());
            }

            if (lastVisitorRecord != null) {
                String oldEstimateVisitorTime = DateUtil.formatDate(lastVisitorRecord.getEstimateVisitorTime(), "MM-dd HH:mm");
                String newEstimateVisitorTime = DateUtil.formatDate(visitorRecord.getEstimateVisitorTime(), "MM-dd HH:mm");
                rsp.setStrError("您的预约时间已有 " + oldEstimateVisitorTime + " 改为 " + newEstimateVisitorTime);
            }

            // 从微信服务器下载图片
            if (StringUtils.isNotEmpty(req.getAccessToken()) && StringUtils.isNotEmpty(req.getImgServerId())) {
                byte[] bytes = downloadMedia(req.getAccessToken(), req.getImgServerId());
                if (bytes != null && bytes.length > 0) {
                    visitorImgMapper.insertImg(visitorRecord.getId(), bytes);
                }
            }
            rsp.setResult(WechatBusinessRsp.SUCCESS);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("服务器异常！");
            logger.error("访客申请访问异常：{}", e);
        }
        return rsp;
    }

    /**
     * 获取媒体文件
     *
     * @param accessToken 接口访问凭证
     * @param mediaId     媒体文件id
     */
    public static byte[] downloadMedia(String accessToken, String mediaId) {

        String filePath = null;
        // 拼接请求地址
        String requestUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
        requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("MEDIA_ID", mediaId);
        HttpURLConnection conn = null;
        try {
            URL url = new URL(requestUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setRequestMethod("GET");

            BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            for (int readNum; (readNum = bis.read(buf)) != -1; ) {
                bos.write(buf, 0, readNum);
            }
            bis.close();
            return bos.toByteArray();
        } catch (Exception e) {
            logger.error("从微信服务器下载文件异常：{}", e);
        } finally {

            if (conn != null) {
                conn.disconnect();
            }
        }
        return null;
    }

    /**
     * 访客申请通过，向visitor_record_send表中插入数据，TOB定时器检测向车场发送访客记录
     *
     * @param visitorRecord 访客记录
     */
    private String saveVisitorRecordSend(VisitorRecord visitorRecord) {
        String personName = "";
        String mobile = visitorRecord.getMobile();
        // 根据手机号查找人员
        List<Person> personList = personMapper.getByPhone(mobile);
        if (personList != null) {
            for (Person person : personList) {
                // 判断会员所在车场是否开启 访客预约 功能
                LocalAdminpara localAdminpara = localAdminparaMapper.getByParkingIdAndParaKey(person.getParkingId(), LocalAdminpara.USED_VISITOR_SYSTEM);
                if (localAdminpara != null && "1".equals(localAdminpara.getParaValue())) {
                    // 会员是否是被访客
                    if (person.getInterviewee() != null && person.getInterviewee() == 1) {
                        if (StringUtils.isNotEmpty(person.getName())) {
                            personName = person.getName().substring(0, 1) + "**";
                        }
                        // 保存记录
                        VisitorRecordSend visitorRecordSend = new VisitorRecordSend(visitorRecord.getId(), person.getParkingId());
                        visitorRecordSendMapper.insertVisitorRecordSend(visitorRecordSend);
                    }
                }
            }
        }
        return personName;
    }


    private String getIntervieweeName(VisitorRecord visitorRecord) {
        String personName = "";
        String mobile = visitorRecord.getMobile();
        // 根据手机号查找人员
        List<Person> personList = personMapper.getByPhone(mobile);
        if (personList != null) {
            for (Person person : personList) {
                // 判断会员所在车场是否开启 访客预约 功能
                LocalAdminpara localAdminpara = localAdminparaMapper.getByParkingIdAndParaKey(person.getParkingId(), LocalAdminpara.USED_VISITOR_SYSTEM);
                if (localAdminpara != null && "1".equals(localAdminpara.getParaValue())) {
                    // 会员是否是被访客
                    if (person.getInterviewee() != null && person.getInterviewee() == 1) {
                        if (StringUtils.isNotEmpty(person.getName())) {
                            personName = person.getName().substring(0, 1) + "**";
                        }
                    }
                }
            }
        }
        return personName;
    }

    @Override
    public WechatProcessVisitRsp processVisit(WechatProcessVisitReq req) {
        WechatProcessVisitRsp rsp = new WechatProcessVisitRsp();
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User interviewee = checkParam.getUserByOpenid(req.getOpenid());

            VisitorRecord visitorRecord = visitorRecordMapper.getById(req.getOrderId());
            if (visitorRecord == null || interviewee.getId() != visitorRecord.getIntervieweeId()) {
                rsp.setStrError("未找到访客预约信息！");
                return rsp;
            }

            if (visitorRecord.getStatus() != VisitorRecord.STATUS_WAIT_PASS) {
                rsp.setStrError("该订单已处理！");
                return rsp;
            }

            User visitor = userMapper.getById(visitorRecord.getVisitorId());
            if (visitor == null) {
                rsp.setStrError("未找到访客信息！");
                return rsp;
            }

            visitorRecord.setStatus(req.getProcessedResults());
            visitorRecord.setRejectMemo(req.getRejectMemo());

            if (req.getProcessedResults() == VisitorRecord.STATUS_PASS) {   // 访客通过
                // 更新订单状态
                visitorRecordMapper.updateStatusById(req.getProcessedResults(), req.getOrderId());
                // 保存订单需要发送的车场
                String intervieweeName = saveVisitorRecordSend(visitorRecord); // 被访客姓名
                // 微信通知：
                String estimateVisitorTime = DateUtil.formatDate(visitorRecord.getEstimateVisitorTime(), "yyyy-MM-dd HH:mm");
                String endTime = DateUtil.formatDate(visitorRecord.getEndTime(), "yyyy-MM-dd HH:mm");

                String openid = usersWechatMapper.getOpenidByUserIdAndApiUserId(visitor.getId(), visitorRecord.getApiUserId());
                wechatSendService.visitPass(intervieweeName, visitorRecord.getApiUserId(), openid, visitorRecord.getName(), interviewee.getMobile(), estimateVisitorTime, endTime, visitorRecord.getOrderNo());
            } else {    // 访客被拒
                // 更新订单状态
                visitorRecord.setEndTime(visitorRecord.getEstimateVisitorTime());
                visitorRecordMapper.rejectVisit(visitorRecord);

                // 微信通知：
                String intervieweeName = getIntervieweeName(visitorRecord); // 被访客姓名
                String estimateVisitorTime = DateUtil.formatDate(visitorRecord.getEstimateVisitorTime(), "yyyy-MM-dd HH:mm");
                String endTime = DateUtil.formatDate(visitorRecord.getEndTime(), "yyyy-MM-dd HH:mm");

                String openid = usersWechatMapper.getOpenidByUserIdAndApiUserId(visitor.getId(), visitorRecord.getApiUserId());

                wechatSendService.visitReject(intervieweeName, visitorRecord.getApiUserId(), openid, visitorRecord.getName(), interviewee.getMobile(), estimateVisitorTime, endTime, visitorRecord.getRejectMemo(), visitorRecord.getMemo());
            }

            rsp.setResult(WechatBusinessRsp.SUCCESS);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("服务器异常！");
            logger.error("受访者同意或拒绝访问异常：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatGetVisitorRecordRsp getVisitorRecord(WechatGetVisitorRecordReq req) {
        WechatGetVisitorRecordRsp rsp = new WechatGetVisitorRecordRsp();
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            checkParam.getUserByOpenid(req.getOpenid());


            VisitorRecord visitorRecord = visitorRecordMapper.getById(req.getOrderId());
            if (visitorRecord == null) {
                rsp.setStrError("未找到访客预约信息！");
                return rsp;
            }

            User user = userMapper.getById(visitorRecord.getVisitorId());
            if (user == null) {
                rsp.setStrError("未找到访客信息！");
                return rsp;
            }

            Integer imageId = visitorImgMapper.getIdByVisitorRecordId(visitorRecord.getId());
            if (imageId != null) {
                String serverAddress = "http://" + basicProperties.getServerAddress() + ":" + basicProperties.getHttpPort();
                rsp.setImgUrl(serverAddress + "/visitorImg/" + imageId);
            }

            rsp.setVisitorName(visitorRecord.getName());
            rsp.setVisitorMobile(user.getMobile());
            rsp.setVisitorMemo(visitorRecord.getMemo());
            rsp.setVisitorPlates(visitorRecord.getPlate());
            rsp.setEstimateVisitorTime(DateUtil.formatDate(visitorRecord.getEstimateVisitorTime(), "yyyy-MM-dd HH:mm"));
            rsp.setStatus(visitorRecord.getStatus());
            String statusDesc = visitorRecord.getStatusDesc();
            rsp.setStatusDesc(statusDesc);
            rsp.setResult(WechatBusinessRsp.SUCCESS);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("服务器异常！");
            logger.error("访客申请访问异常：{}", e);
        }
        return rsp;
    }

    @Override
    public WechatGetMyApplyRsp getMyApply(WechatGetMyApplyReq req) {
        WechatGetMyApplyRsp rsp = new WechatGetMyApplyRsp();
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User visitor = checkParam.getUserByOpenid(req.getOpenid());

            ArrayList<WechatVisitorRecordItem> recordList = new ArrayList<>();
            if (req.getPageNum() == 0) {
                rsp.setCount(visitorRecordMapper.getCountByVisitorId(visitor.getId()));
            }
            System.out.println(req.getPageNum());
            List<VisitorRecord> visitorRecordList = visitorRecordMapper.getByVisitorId(visitor.getId(), req.getPageNum(), req.getPageSize());
            if (visitorRecordList != null) {
                for (VisitorRecord visitorRecord : visitorRecordList) {
                    WechatVisitorRecordItem item = new WechatVisitorRecordItem();
                    item.setVisitorName(visitorRecord.getName());
                    item.setVisitorMobile(visitorRecord.getMobile());
                    item.setVisitorMemo(visitorRecord.getMemo());
                    item.setVisitorPlates(visitorRecord.getPlate() == null ? "" : visitorRecord.getPlate());
                    item.setStatus(visitorRecord.getStatus());
                    item.setStatusDesc(visitorRecord.getStatusDesc());
                    item.setEstimateVisitorTime(DateUtil.formatDate(visitorRecord.getEstimateVisitorTime(), "yyyy-MM-dd HH:mm"));
                    if (visitorRecord.getVisitorTime() != null) {
                        item.setVisitorTime(DateUtil.formatDate(visitorRecord.getVisitorTime(), "yyyy-MM-dd HH:mm"));
                    }
                    item.setEndTime(DateUtil.formatDate(visitorRecord.getEndTime(), "yyyy-MM-dd HH:mm"));
                    item.setRejectMemo(visitorRecord.getRejectMemo());
                    recordList.add(item);
                }
            }
            rsp.setRecordList(recordList);
            rsp.setResult(WechatBusinessRsp.SUCCESS);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("服务器异常！");
            logger.error("访客申请访问异常：{}", e);
        }
        return rsp;
    }

   /* @Override
    public WechatGetFeeRateNewRsp getFeeRateNew(WechatGetFeeRateReq req) {
        WechatGetFeeRateNewRsp rsp = new WechatGetFeeRateNewRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            UsersWechat usersWechat = usersWechatMapper.getByOpenid(req.getOpenid());
            User user = checkParam.getUserByOpenid(req.getOpenid());
            List<AppCar> appCars = appUserCarMapper.getCarByUserId(user.getId());
            if (appCars == null || appCars.size() == 0) {
                rsp.setStrError("没有车辆，无法充值！");
                return rsp;
            }

            // 车牌号：《车场id：《费率信息，车位数等》 》
            Map<String, Map<Integer, FeeRateItemNew>> plateFeeRateMap = new HashMap<>();

            for (AppCar appCar : appCars) {
                List<Car> cars = carMapper.getByPlate(appCar.getPlate());
                if (cars == null || cars.size() == 0) {
                    logger.info("车辆({})未在任何车场登记", appCar.getPlate());
                    continue;
                }
                Map<Integer, FeeRateItemNew> feeRateMap = new HashMap<>();
                for (Car car : cars) {
                    logger.info("车辆({})在车场({})的({})名下登记！", appCar.getPlate(), car.getParkingId(), car.getPersonId());
                    Parking parking = parkingMapper.getParkingById(car.getParkingId());
                    if (parking == null) {
                        continue;
                    }
                    List<FeeGroup> feeRateList = feeGroupMapper.listWechatShowFeeRateByParkingId(car.getParkingId());
                    if (feeRateList == null || feeRateList.size() == 0) {
                        continue;
                    }
                    Integer carportNum = personMapper.getCarportNumByPersonIdAndParkingId(car.getPersonId(), parking.getId());

                    List<FeeRateDetailItem> feeRateDetailItems = new ArrayList<>();
                    for (FeeGroup feeGroup : feeRateList) {
                        FeeRateDetailItem item = new FeeRateDetailItem();
                        item.setBillingType(feeGroup.getBillingType());
                        item.setFee(feeGroup.getFee());
                        item.setId(feeGroup.getId());
                        item.setLocalFeegroupId(feeGroup.getLocalFeegroupId());
                        item.setName(feeGroup.getName());
                        feeRateDetailItems.add(item);
                    }
                    FeeRateItemNew feeRateItemNew = new FeeRateItemNew();
                    feeRateItemNew.setCarportNum(carportNum == null ? 0 : carportNum);
                    feeRateItemNew.setFeeRateList(feeRateDetailItems);
                    feeRateItemNew.setParkingId(parking.getId());
                    feeRateItemNew.setParkingName(parking.getName());
                    feeRateMap.put(parking.getId(), feeRateItemNew);

                }
                if (feeRateMap.size() > 0) {
                    plateFeeRateMap.put(appCar.getPlate(), feeRateMap);
                }
            }
            rsp.setResult(WechatBusinessRsp.SUCCESS);
            rsp.setPlateFeeRateMap(plateFeeRateMap);

        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("无法充值！");
            logger.info("获取月卡充值表单页面异常：{}", e);
        }
        return rsp;
    }*/
   @Override
   public WechatGetFeeRateNewRsp getFeeRateNew(WechatGetFeeRateReq req) {
       WechatGetFeeRateNewRsp rsp = new WechatGetFeeRateNewRsp();
       rsp.setOpenid(req.getOpenid());
       rsp.setResult(WechatBusinessRsp.FAIL);
       try {
           UsersWechat usersWechat = usersWechatMapper.getByOpenid(req.getOpenid());
           User user = checkParam.getUserByOpenid(req.getOpenid());
           List<AppCar> appCars = appUserCarMapper.getCarByUserId(user.getId());
           if (appCars == null || appCars.size() == 0) {
               rsp.setStrError("没有车辆，无法充值！");
               return rsp;
           }

           // 车牌号：《车场id：《费率信息，车位数等》 》
           List<FeeRateItemNew> itemNews = new ArrayList<>();
           for (AppCar appCar : appCars) {
               List<Car> cars = carMapper.getByPlate(appCar.getPlate());
               if (cars == null || cars.size() == 0) {
                   logger.info("车辆({})未在任何车场登记", appCar.getPlate());
                   continue;
               }
               for (Car car : cars) {
                   FeeRateItemNew feeRateItemNew = new FeeRateItemNew();
                   logger.info("车辆({})在车场({})的({})名下登记！", appCar.getPlate(), car.getParkingId(), car.getPersonId());
                   Parking parking = parkingMapper.getParkingById(car.getParkingId());
                   if (parking == null) {
                       continue;
                   }
                   List<FeeGroup> feeRateList = feeGroupMapper.listWechatShowFeeRateByParkingId(car.getParkingId());
                   if (feeRateList == null || feeRateList.size() == 0) {
                       continue;
                   }
                   Integer carportNum = personMapper.getCarportNumByPersonIdAndParkingId(car.getPersonId(), parking.getId());

                   List<FeeRateDetailItem> feeRateDetailItems = new ArrayList<>();
                   for (FeeGroup feeGroup : feeRateList) {
                       if(feeGroup.getLocalFeegroupId().equals(car.getFeeGroupId())) {
                           feeRateItemNew.setBillingType(feeGroup.getBillingType());
                           feeRateItemNew.setFee(feeGroup.getFee());
                           feeRateItemNew.setId(feeGroup.getId());
                           feeRateItemNew.setLocalFeegroupId(feeGroup.getLocalFeegroupId());
                           feeRateItemNew.setName(feeGroup.getName());
                           break;
                       }
                   }
                   if(feeRateItemNew.getId()==null||feeRateItemNew.getLocalFeegroupId()==null){
                       continue;
                   }
                   feeRateItemNew.setCarportNum(carportNum == null ? 0 : carportNum);
                   feeRateItemNew.setFeeRateList(feeRateDetailItems);
                   feeRateItemNew.setParkingId(parking.getId());
                   feeRateItemNew.setParkingName(parking.getName());
                   feeRateItemNew.setPlate(car.getLicense());
                   feeRateItemNew.setPersonId(car.getPersonId());
                   feeRateItemNew.setEndTime(DateUtil.formatDate(car.getEndTime(),"yyyy-MM-dd"));
                   boolean succ = false;
                   for (FeeRateItemNew n:itemNews){
                       if(n.getParkingId().equals(car.getParkingId())&&n.getPersonId().equals(car.getPersonId())){
                           succ = true;
                           n.setPlate(n.getPlate()+","+car.getLicense());
                           break;
                       }
                   }
                   if(!succ){
                       itemNews.add(feeRateItemNew);
                   }
               }
           }
            int i = 0;
           List<FeeRateItemGroup> groups = new ArrayList<>();
           FeeRateItemGroup group= null;
           List<FeeRateItemNew> news = new ArrayList<>();
            for(FeeRateItemNew itemNew:itemNews){
                i++;
                if(group==null){
                    group = new FeeRateItemGroup();
                    group.setParkingId(itemNew.getParkingId());
                    group.setParkingName(itemNew.getParkingName());
                }
                if(itemNew.getParkingId().equals(group.getParkingId())){
                    news.add(itemNew);
                }else {
                    group.setList(news);
                    news = new ArrayList<>();
                    groups.add(group);
                    group = new FeeRateItemGroup();
                    group.setParkingId(itemNew.getParkingId());
                    group.setParkingName(itemNew.getParkingName());
                    news.add(itemNew);
                }
                if(i==itemNews.size()){
                    group.setList(news);
                    groups.add(group);
                }
            }
           rsp.setResult(WechatBusinessRsp.SUCCESS);
           rsp.setData(groups);
       } catch (CustomException e) {
           rsp.setStrError(e.getMessage());
       } catch (Exception e) {
           rsp.setStrError("无法充值！");
           logger.info("获取月卡充值表单页面异常：{}", e);
       }
       return rsp;
   }
    @Override
    public byte[] getVisitorImg(Integer imageId) {
        VisitorImg visitorImg = visitorImgMapper.getById(imageId);
        if (visitorImg != null) {
            return visitorImg.getImg();
        }
        return null;
    }


    @Override
    public WechatGetCarWashCouponsRsp getCarWashCoupons(WechatGetCarWashCouponsReq req) {
        WechatGetCarWashCouponsRsp rsp = new WechatGetCarWashCouponsRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User user = checkParam.getUserByOpenid(req.getOpenid());
            List<LocalCarWashCoupon> allCarWashCouponList = getCarWashCoupons(user);

            List<WechatGetCarWashCouponsItem> couponList = new ArrayList<>();
            for (LocalCarWashCoupon carWashCoupon : allCarWashCouponList) {
                WechatGetCarWashCouponsItem item = new WechatGetCarWashCouponsItem();
                item.setLocalCarwashCouponId(carWashCoupon.getLocalCarwashCouponId());
                item.setPlates(carWashCoupon.getPlates());
                item.setEndTime(DateUtil.formatDate(carWashCoupon.getEndTime(), "yyyy-MM-dd 23:59:59"));
                item.setSource(carWashCoupon.getSourceDesc());
                item.setAllCount(carWashCoupon.getCouponCount());
                item.setUsedCount(carWashCoupon.getUsedCount());
                item.setCanUseCount(carWashCoupon.getCouponCount() - carWashCoupon.getUsedCount());
                item.setParkingId(carWashCoupon.getParkingId());
                couponList.add(item);
            }

            rsp.setResult(WechatBusinessRsp.SUCCESS);
            rsp.setCouponList(couponList);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("获取洗车券失败！");
            logger.error("{}", e);
        }
        return rsp;
    }

    private List<LocalCarWashCoupon> getCarWashCoupons(User user) {
        Map<Integer, Set<Integer>> parkingPersonIdList = userService.getParkingPersonIdByUserId(user.getId());

        List<LocalCarWashCoupon> allCarWashCouponList = new ArrayList<>();
        for (Map.Entry<Integer, Set<Integer>> entry : parkingPersonIdList.entrySet()) {
            Integer parkingId = entry.getKey();
            Set<Integer> personIdList = entry.getValue();
            for (Integer personId : personIdList) {
                List<LocalCarWashCoupon> carWashCouponList = localCarWashCouponMapper.getCanUsedByPersonIdAndParkingId(personId, parkingId);
                if (carWashCouponList != null) {
                    for (LocalCarWashCoupon carWashCoupon : carWashCouponList) {
                        if (carWashCoupon != null) {
                            if (carWashCoupon.getEndTime().getTime() < System.currentTimeMillis()) {
                                continue;
                            }
                            Integer usedCount = carWashDetailMapper.countByCouponIdAndParkingId(carWashCoupon.getLocalCarwashCouponId(), parkingId);
                            if (usedCount == null) {
                                usedCount = 0;
                            }
                            if (carWashCoupon.getCouponCount() <= usedCount) {
                                continue;
                            }

                            String plates = carMapper.listPlateByPersonIdAndParkingId(carWashCoupon.getPersonId(), parkingId);
                            if (StringUtils.isEmpty(plates)) {
                                continue;
                            }

                            carWashCoupon.setUsedCount(usedCount);
                            carWashCoupon.setPlates(plates);
                            allCarWashCouponList.add(carWashCoupon);
                        }
                    }
                }
            }
        }
        return allCarWashCouponList;
    }

    @Override
    public WechatCarWashRsp carWash(WechatCarWashReq req) {
        WechatCarWashRsp rsp = new WechatCarWashRsp();
        rsp.setOpenid(req.getOpenid());
        rsp.setResult(WechatBusinessRsp.FAIL);
        try {
            User user = checkParam.getUserByOpenid(req.getOpenid());
            List<LocalCarWashCoupon> allCarWashCouponList = getCarWashCoupons(user);
            if (allCarWashCouponList == null || allCarWashCouponList.size() == 0) {
                rsp.setStrError("没有洗车券，无法洗车！");
                return rsp;
            }

            int allCanUsedCount = 0;
            for (LocalCarWashCoupon localCarWashCoupon : allCarWashCouponList) {
                allCanUsedCount += localCarWashCoupon.getCouponCount() - localCarWashCoupon.getUsedCount();
            }

            LocalCarWashCoupon localCarWashCoupon = allCarWashCouponList.get(0);

            CarWashDetail carWashDetail = new CarWashDetail();
            carWashDetail.setParkingId(localCarWashCoupon.getParkingId());
            carWashDetail.setCouponId(localCarWashCoupon.getLocalCarwashCouponId());
            int canUseCount = localCarWashCoupon.getCouponCount() - localCarWashCoupon.getUsedCount();
            carWashDetail.setBeforeUseCount(canUseCount);
            carWashDetail.setAfterUseCount(canUseCount - 1);
            carWashDetail.setUseTime(new Date());
            carWashDetailMapper.insert(carWashDetail);

            MqCarWashDetailReq mqCarWashDetailReq = new MqCarWashDetailReq();
            BeanUtils.copyProperties(carWashDetail, mqCarWashDetailReq);
            mqCarWashDetailReq.setUseTimeSecond(DateUtil.convertDate2Seconds(carWashDetail.getUseTime()));
            mqCarWashDetailReq.setOptid(MqBusinessOpt.TOC_SEND_CAR_WASH_DETAIL);
            String uuid = UUID.randomUUID().toString();
            mqCarWashDetailReq.setUuid(uuid);
            sendMsgService.send(mqCarWashDetailReq);

            rsp.setPlates(localCarWashCoupon.getPlates());
            rsp.setUsedTime(DateUtil.formatCurrentTime("yyyy-MM-dd"));
            rsp.setAllCanUsedCount(allCanUsedCount);
            rsp.setResult(WechatBusinessRsp.SUCCESS);
        } catch (CustomException e) {
            rsp.setStrError(e.getMessage());
        } catch (Exception e) {
            rsp.setStrError("洗车失败！");
            logger.error("{}", e);
        }
        return rsp;
    }
}
